home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / snip0493.zip / TAIL.C < prev    next >
C/C++ Source or Header  |  1993-04-05  |  5KB  |  192 lines

  1. /*
  2. **  TAIL.C  Display the last "n" lines of a file (5 lines by default).
  3. **  Written February 4, 1986 by Joe Huffman
  4. **  Modified October 5, 1986 by Joe Huffman
  5. **    Utilize prototyping, fixed a bug, added (a few) comments and help.
  6. **
  7. **  Not copyrighted.
  8. */ 
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13.  
  14. unsigned char head1[] = {"\n------- \""},
  15.               head2[] = {" -------\n"};
  16. FILE *fp;
  17. int filenum, cc;
  18. unsigned int linenum = 5, indx;
  19. long int *tail;
  20. void help (void);
  21. void getlinenum (int n, unsigned char *str[]);
  22. void gettail (void);
  23. void LtoA (long int val, unsigned char *cp);
  24.  
  25. main (int argc, unsigned char *argv[])
  26. {
  27.       if (argc <= 1)
  28.       {
  29.             help ();
  30.             return (1);
  31.       }
  32.  
  33.       getlinenum (argc, argv);
  34.  
  35.       for (filenum = 1; filenum < argc; ++filenum)
  36.       {
  37.             if (*argv[filenum] == '/')
  38.                   continue;
  39.             fp = fopen (argv[filenum], "rb");
  40.             if (!fp)
  41.             {
  42.                   fputs (head1, stderr);
  43.                   fputs (argv[filenum], stderr);
  44.                   fputs ("\" not found.", stderr);
  45.                   fputs (head2, stderr);
  46.             }
  47.             else
  48.             {
  49.                   fputs (head1, stdout);
  50.                   fputs (argv[filenum], stdout);
  51.                   gettail ();
  52.                   fputs (head2, stdout);
  53.                   for (cc = getc (fp); cc != EOF; cc = getc (fp))
  54.                         fputc (cc, stdout);
  55.                   fclose (fp);
  56.             }
  57.       }
  58. }
  59.  
  60. /*
  61. **  Get the number of lines to display at the "tail" of each file from
  62. **  the command line.
  63. */
  64.  
  65. void getlinenum (int n, unsigned char *str[])
  66. {
  67.       for (--n; n; --n)
  68.       {
  69.             ++str;
  70.             if (**str == '/')
  71.             {
  72.                   linenum = atoi (*(str) + 1);
  73.                   if (linenum <= 0)
  74.                         linenum = 5;
  75.             }
  76.       }
  77.       linenum++;
  78.       /* Because we save a pointer to the end of the PREVIOUS line. */
  79. }
  80.  
  81. /*
  82. **  Set the file pointer "fp" to "linenum - 1" lines before the end of
  83. **  the file.
  84. */
  85.  
  86. void gettail (void)
  87. {
  88.       unsigned char outstr[15];
  89.       void *malloc (unsigned int);
  90.       unsigned long int currline = 0L;
  91.  
  92.       tail = (long int *)malloc (sizeof(*tail) * linenum);
  93.       if (!tail)
  94.       {
  95.             fputs ("Insufficient memory.", stderr);
  96.             exit (1);
  97.       }
  98.       tail[0] = ftell (fp);
  99.       indx = 0;
  100.  
  101.       for (cc = getc (fp); cc != EOF; cc = getc (fp))
  102.       {
  103.             if (cc == '\r')
  104.             {
  105.                   ++currline;
  106.                   cc = getc (fp);
  107.                   if (cc != '\n')
  108.                         ungetc (cc, fp);
  109.                   ++indx;
  110.                   indx %= linenum;
  111.                   tail[indx] = ftell (fp);
  112.             }
  113.             else
  114.             {
  115.                   if (cc == '\n')
  116.                   {
  117.                         ++currline;
  118.                         cc = getc (fp);
  119.                         if (cc != '\r')
  120.                               ungetc (cc, fp);
  121.                         ++indx;
  122.                         indx %= linenum;
  123.                         tail[indx] = ftell (fp);
  124.                   }
  125.             }
  126.       }
  127.       fputs ("\" ", stdout);
  128.       LtoA (currline, outstr);
  129.       fputs (outstr, stdout);
  130.       fputs (" lines", stdout);
  131.       if (currline >= linenum - 1)
  132.       {
  133.             indx++;
  134.             indx %= linenum;
  135.       }
  136.       else  indx = 0;
  137.  
  138.       if (fseek (fp, tail[indx], 0) == -1)
  139.       {
  140.             fputs ("\nFile seek error.", stderr);
  141.             exit (1);
  142.       }
  143.       free (tail);
  144. }
  145.  
  146. /*
  147. **  long integer to ASCII.  Use this function rather than the ltoa()
  148. **  library function to save many bytes in the executable file.
  149. */
  150.  
  151. void LtoA (long int val, unsigned char *cp)
  152. {
  153.       unsigned char tempc[15], *tcptr;
  154.       int sign;
  155.       static unsigned char dig[] = {"0123456789"};
  156.  
  157.       if (val < 0)
  158.       {
  159.             val = -val;
  160.             sign = 1;
  161.       }
  162.       else  sign = 0;
  163.  
  164.       *(tcptr = tempc + 11) = '\0';
  165.       do 
  166.       {
  167.             *--tcptr = dig[(int)(val % 10)];
  168.       }while (val /= 10);
  169.       if (sign)
  170.             *--tcptr = '-';
  171.       strcpy (cp, tcptr);
  172. }
  173.  
  174. /*
  175. **  Tell the user what the program is and how to use it.
  176. */
  177.  
  178. void help (void)
  179. {
  180.       char *ptr;
  181.       static char help_str[] = { "Command error: No file(s) specified.\n"
  182.             "Written by Joe Huffman.\n"
  183.             "TAIL is a program that prints out only the last lines of a "
  184.             "program.\nusage:\nTAIL filename [filename] [/n]\n\n"
  185.             "filename - The name of a valid file, wildcards accepted.\n"
  186.             "n - number of lines to print out, 5 by default."
  187.             };
  188.  
  189.       for (ptr = &help_str[0]; *ptr; ptr++)
  190.             fputc (*ptr, stdout);
  191. }
  192.